<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>复杂工厂模式</title>
</head>
<body>
	<h1>复杂工厂模式</h1>
</body>
<script type="text/javascript">

    // 定义自行车的构造函数
    var BicycleShop = function(name){
        this.name = name;
        this.method = function(){
            return this.name;
        }
    };
    BicycleShop.prototype = {
        constructor: BicycleShop,
        /*
        * 买自行车这个方法
        * @param {model} 自行车型号
        */
        sellBicycle: function(model){
            var bicycle = this.createBicycle(model);
            // 执行A业务逻辑
            bicycle.A.call(this);

            // 执行B业务逻辑
            bicycle.B();

            return bicycle;
        },
        createBicycle: function(model){
            throw new Error("父类是抽象类不能直接调用，需要子类重写该方法");
        }
    };
    // 实现原型继承
    function extend(Sub,Sup) {
        //Sub表示子类，Sup表示超类
        // 首先定义一个空函数
        var F = function(){};

        // 设置空函数的原型为超类的原型
        F.prototype = Sup.prototype; 

        // 实例化空函数，并把超类原型引用传递给子类
        Sub.prototype = new F();
                    
        // 重置子类原型的构造器为子类自身
        Sub.prototype.constructor = Sub;
                    
        // 在子类中保存超类的原型,避免子类与超类耦合
        Sub.sup = Sup.prototype;

        if(Sup.prototype.constructor === Object.prototype.constructor) {
            // 检测超类原型的构造器是否为原型自身
            Sup.prototype.constructor = Sup;
        }
    }
    var BicycleChild = function(name){
        this.name = name;
        // 继承构造函数父类中的属性和方法
        BicycleShop.call(this,name);
    };
        // 子类继承父类原型方法
    extend(BicycleChild,BicycleShop);
    // BicycleChild 子类重写父类的方法
    BicycleChild.prototype.createBicycle = function(){
        var A = function(){
            console.log(`执行A业务操作${this.name}`);    
        };
        var B = function(){
            console.log("执行B业务操作");
        };
        return {
            A: A,
            B: B
        }
    }
    var childClass = new BicycleChild("龙恩");

    childClass.sellBicycle()
    console.log(childClass);
</script>
</html>